<?php

namespace EthanZ\LaravelExt\Models\Traits;

use EthanZ\LaravelExt\Models\GlobalScopes\SoftDelete as GlobalSoftDelete;
use EthanZ\LaravelExt\Exceptions\NormalException;
use Illuminate\Database\Eloquent\Builder;

/**
 * 自定义软删除
 *
 * @package EthanZ\LaravelExt\Models\Traits
 */
trait SoftDelete
{

    /*
    |--------------------------------------------------------------------------
    | 自带的不是时间软删除,而是以null|1来判断是否删除.
    |--------------------------------------------------------------------------
    */


    /**
     * 全局作用域
     */
    public static function bootSoftDelete(): void
    {
        if (static::DELETED_AT) {
            static::addGlobalScope(new GlobalSoftDelete);
        }
    }


    /**
     * 自定义软删除
     *
     * @param int $type 1:软删除 0:恢复.
     *
     * @throws NormalException
     */
    public function softDelete(int $type = 1): void
    {
        // 获取软删除字段.
        $deletedAt = static::DELETED_AT;
        if ($deletedAt) {
            // 软删除.
            $this->timestamps = false;
            $this->$deletedAt = $type ? time() : 0;

            $this->save();
        } else {
            throw new NormalException('BAS_DAT_001');
        }
    }


    /**
     * 自定义软删除
     *
     * @param Builder $query 查询.
     * @param int     $type  1:软删除 0:恢复.
     *
     * @throws NormalException
     */
    public function scopeSoftDelete(Builder $query, int $type = 1): int
    {
        // 获取软删除字段.
        $deletedAt = static::DELETED_AT;
        if ($deletedAt) {
            $deletedAt        = static::query()->getModel()->getTable() . '.' . $deletedAt;
            $this->timestamps = false;

            return $query->withoutGlobalScope('delete')
                ->update(
                    [
                        $deletedAt => $type ? time() : 0,
                    ]
                );
        }

        throw new NormalException('BAS_DAT_001');
    }


    /**
     * 查询自定义软删除数据
     *
     * @param Builder $query 查询.
     *
     * @return Builder
     */
    public function scopeSoftDeleteData(Builder $query): Builder
    {
        // 获取软删除字段.
        $deletedAt = static::DELETED_AT;
        if ($deletedAt) {
            $deletedAt = static::query()->getModel()->getTable() . '.' . $deletedAt;
            $query->withoutGlobalScope('delete')
                ->where($deletedAt, '>', 0);
        }

        return $query;
    }
}